import xml.etree.ElementTree as ET

# 解析ARXML文件
def parse_arxml(file_path):
    tree = ET.parse(file_path)
    root = tree.getroot()
    return root

# 提取所有结构体及其成员
def extract_structures(root):
    structures = {}
    for data_type in root.findall('.//{http://autosar.org/schema/r4.0}STD-CPP-IMPLEMENTATION-DATA-TYPE'):
        if data_type.find('{http://autosar.org/schema/r4.0}CATEGORY').text == 'STRUCTURE':
            struct_name = data_type.find('{http://autosar.org/schema/r4.0}SHORT-NAME').text
            members = []

            for sub_element in data_type.findall('.//{http://autosar.org/schema/r4.0}CPP-IMPLEMENTATION-DATA-TYPE-ELEMENT'):
                member_name = sub_element.find('{http://autosar.org/schema/r4.0}SHORT-NAME').text
                member_type_ref = sub_element.find('.//{http://autosar.org/schema/r4.0}TYPE-REFERENCE-REF')
                if member_type_ref is not None:
                    member_type = member_type_ref.text.split('/')[-1]
                    if member_type.startswith('CS_'):
                        member_type = resolve_cs_type(root, member_type)
                else:
                    member_type = 'int'  # 默认类型
                    print(f"Warning: TYPE-REFERENCE-REF not found for member {member_name} in struct {struct_name}, using default type 'int'")
                desc = sub_element.find('{http://autosar.org/schema/r4.0}DESC/{http://autosar.org/schema/r4.0}L-2').text if sub_element.find('{http://autosar.org/schema/r4.0}DESC/{http://autosar.org/schema/r4.0}L-2') is not None else ''
                members.append((member_name, member_type, desc))

            structures[struct_name] = members
    return structures

# 提取所有枚举值
def extract_enums(root):
    enums = {}
    for compu_method in root.findall('.//{http://autosar.org/schema/r4.0}COMPU-METHOD'):
        if compu_method.find('{http://autosar.org/schema/r4.0}CATEGORY').text == 'TEXTTABLE':
            enum_name = compu_method.find('{http://autosar.org/schema/r4.0}SHORT-NAME').text
            enum_values = []
            for compu_scale in compu_method.findall('.//{http://autosar.org/schema/r4.0}COMPU-SCALE'):
                short_label = compu_scale.find('{http://autosar.org/schema/r4.0}SHORT-LABEL')
                if short_label is not None:
                    enum_value = short_label.text
                    enum_values.append(enum_value)
                else:
                    print(f"Warning: SHORT-LABEL not found in COMPU-SCALE for enum {enum_name}")
            enums[enum_name] = enum_values
    return enums

# 提取所有数组
def extract_arrays(root):
    arrays = {}
    for data_type in root.findall('.//{http://autosar.org/schema/r4.0}STD-CPP-IMPLEMENTATION-DATA-TYPE'):
        if data_type.find('{http://autosar.org/schema/r4.0}CATEGORY').text == 'ARRAY':
            array_name = data_type.find('{http://autosar.org/schema/r4.0}SHORT-NAME').text
            array_size = data_type.find('{http://autosar.org/schema/r4.0}ARRAY-SIZE').text
            element_type_ref = data_type.find('.//{http://autosar.org/schema/r4.0}TYPE-REFERENCE-REF')
            if element_type_ref is not None:
                element_type = element_type_ref.text.split('/')[-1]
                if element_type.startswith('CS_'):
                    element_type = resolve_cs_type(root, element_type)
            else:
                element_type = 'int'  # 默认类型
                print(f"Warning: TYPE-REFERENCE-REF not found for array {array_name}, using default type 'int'")
            desc = data_type.find('{http://autosar.org/schema/r4.0}DESC/{http://autosar.org/schema/r4.0}L-2').text if data_type.find('{http://autosar.org/schema/r4.0}DESC/{http://autosar.org/schema/r4.0}L-2') is not None else ''
            arrays[array_name] = (element_type, array_size, desc)
    return arrays

# 解析CS_前缀的类型
def resolve_cs_type(root, type_name):
    # 尝试查找枚举类型
    for compu_method in root.findall('.//{http://autosar.org/schema/r4.0}COMPU-METHOD'):
        if compu_method.find('{http://autosar.org/schema/r4.0}SHORT-NAME').text == type_name:
            return 'int'  # 假设CS_前缀的类型是枚举类型，用int替代
    # 尝试查找自定义类型
    for data_type in root.findall('.//{http://autosar.org/schema/r4.0}STD-CPP-IMPLEMENTATION-DATA-TYPE'):
        if data_type.find('{http://autosar.org/schema/r4.0}SHORT-NAME').text == type_name:
            return type_name  # 假设CS_前缀的类型是自定义类型
    return 'int'  # 默认情况下用int替代

# 生成C语言头文件代码
def generate_c_header(structures, enums, arrays):
    header_code = []
    header_code.append('#ifndef VAR_H\n')
    header_code.append('#define VAR_H\n')
    header_code.append('#include <stdint.h>\n')

    for struct_name, members in structures.items():
        header_code.append(f'typedef struct {{\n')
        for member_name, member_type, desc in members:
            if desc:
                header_code.append(f'    // {desc}\n')
            header_code.append(f'    {member_type} {member_name};\n')
        header_code.append(f'}} {struct_name};\n')

    for enum_name, enum_values in enums.items():
        header_code.append(f'typedef enum {{\n')
        for enum_value in enum_values:
            header_code.append(f'    {enum_value},\n')
        header_code.append(f'}} {enum_name};\n')

    for array_name, (element_type, array_size, desc) in arrays.items():
        if desc:
            header_code.append(f'// {desc}\n')
        header_code.append(f'typedef {element_type} {array_name}[{array_size}];\n')

    header_code.append('#endif // VAR_H\n')
    return ''.join(header_code)

# 主函数
def main():
    file_path = 'InterDomain.arxml'
    root = parse_arxml(file_path)
    structures = extract_structures(root)
    enums = extract_enums(root)
    arrays = extract_arrays(root)
    header_code = generate_c_header(structures, enums, arrays)
    
    # 将结果写入var.h文件
    with open('var.h', 'w') as file:
        file.write(header_code)

if __name__ == '__main__':
    main()